package com.hoe.tsb.fraft.net;

import com.hoe.tsb.Configuration;
import com.hoe.tsb.fraft.exception.FRaftException;

import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 数据交换器构造工厂类
 * </p>
 *
 * @author hoe
 * @since 2022/11/21
 */
public class ExchangerFactory {

    private static final Map<String, Class<? extends Exchanger>> EXG_MAP = new HashMap<>(2);

    /**
     * 目前只实现了UDP的，暂时直接把常量以“魔法变量”的方式进行使用
     */
    static {
        EXG_MAP.put("udp", UdpExchanger.class);
    }

    public static Exchanger getExchanger(Configuration configuration) {
        String key = configuration.getExchanger();
        Class<? extends Exchanger> exgCls = EXG_MAP.get(key);
        if (exgCls == null) {
            throw new FRaftException("未知的数据交换器：" + key);
        }

        //直接调用含配置的构造方法
        try {
            Constructor<?>[] csts = exgCls.getDeclaredConstructors();
            for (Constructor<?> cst : csts) {
                if (cst.getParameterCount() == 1 && cst.getParameters()[0].getType().isAssignableFrom(Configuration.class)) {
                    return (Exchanger) cst.newInstance(configuration);
                }
            }
            throw new FRaftException("名为" + key + "的数据交换器无包含配置类的构造方法");
        } catch (Exception e) {
            throw new FRaftException("构建数据交换器错误", e);
        }
    }
}
